#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "messaggio.h"


/*
 * Procedura che resetta il contenuto del messaggio, per rendere più efficente
 * la gestione della struttura dati, visto che molti campi sono a default nella
 * maggior parte dei casi
 *
 * @param Puntatore di tipo messaggio, usato per l'azzeramento dei campi
 */
void resettaMessaggio(messaggio * msx) {

	//Imposto i campi di msx a defaul
	msx -> sender = NULL;
	msx -> receiver = NULL;
	msx -> msglen = 0;
	msx -> msg = NULL;
}


/*
 * Funzione che restituisce la grandezza del messaggio, poichè sizeof non
 * prende in considerazione la lunghezza delle stringhe che sono contenute
 * nella struttura messaggio
 *
 * @param Puntatore di tipo messaggio, usato per il controllo della lunghezza dei campi
 * @return Intero che rappresenta la lunghezza dei campi
 */
int grandezzaMessaggio(messaggio * msx) {

	//Variabile di appoggio per la grandezza
	int grandezza = 0;

	//Ottengo la grandezza di tutti i campi
	grandezza += sizeof(char) + 1;
	if(msx -> sender == NULL)
		grandezza += 1;
	else
		grandezza += strlen(msx -> sender) + 1;
	if(msx -> receiver == NULL)
			grandezza += 1;
		else
			grandezza += strlen(msx -> receiver) + 1;
	grandezza += numeroCifre(msx -> msglen) + 1;
	if(msx -> msglen == 0)
		grandezza += 1;
	else
		grandezza += msx -> msglen;

	//Ritorno il valore esatto
	return grandezza;
}


/*
 * Procedura che inserisce la struttura dati messaggio all'interno di un vettore
 * di caratteri
 *
 * @param Puntatore di tipo messaggio, usato per compilare il secondo parametro
 * @param Vettore di caratteri che contiene l'intera struttura dati
 */
void impacchettaMessaggio(messaggio * msx, char buffer[]) {

	//Variabile utile per la gestione della lunghezza del messaggio (int)
	char msglen[sizeof(int) + 1];

	//Copio tutto il contenuto della struttura all'interno di buffer
	strcpy(buffer, "");
	buffer[0] = msx -> type;
	strcat(buffer, ":");
	if(msx -> sender == NULL)
		strcat(buffer, " ");
	else
		strcat(buffer, msx -> sender);
	strcat(buffer, ":");
	if(msx -> receiver == NULL)
		strcat(buffer, " ");
	else
		strcat(buffer, msx -> receiver);
	strcat(buffer, ":");
	sprintf(msglen, "%d", msx -> msglen);
	strcat(buffer, msglen);
	strcat(buffer, ":");
	if(msx -> msg == NULL)
		strcat(buffer, " ");
	else
		strcat(buffer, msx -> msg);
}


/*
 * Procedura che depacchetta la struttura dati dal buffer alla struttura
 * messaggio
 *
 * @param Vettore di caratteri che contiene l'intera struttura dati
 * @param Puntatore di tipo messaggio, usato per l'inserimento dei dati da buffer
 */
void depacchettaMessaggio(messaggio * msx, char buffer[]) {

	//Variabile temporanea per la gestione dei campi
	char *temp;

	//Controllo buffer per compilare i campi della struttura messaggio
	temp = strtok(buffer, ":");
	msx -> type = temp[0];
	temp = strtok(NULL, ":");
	if(temp == NULL)
		msx -> sender = NULL;
	else {
		msx -> sender = malloc(sizeof(char) * (strlen(temp)));
		strcpy(msx -> sender, temp);
	}
	temp = strtok(NULL, ":");
	if(temp == NULL)
		msx -> receiver = NULL;
	else {
		msx -> receiver = malloc(sizeof(char) * (strlen(temp)));
		strcpy(msx -> receiver, temp);
	}
	sscanf(strtok(NULL, ":"), "%d", &msx -> msglen);
	temp = strtok(NULL, "\0");
	if(temp == NULL)
		msx -> msg = NULL;
	else {
		msx -> msg = malloc(sizeof(char) * (msx -> msglen));
		strcpy(msx -> msg, temp);
	}
}


/*
 * Funzione ricorsiva per la lettura del numero di cifre dalla lunghezza del messaggio
 * in modo tale da risolvere in modo corretto la grandezza del messaggio
 *
 * @param Intero che contiene il numero da cui ricavare il numero di cifre
 * @return Intero che rappresenta il numero di cifre del parametro inserito
 */
int numeroCifre(int num) {
	if(((int)num / 10) == 0)
		return 1;
	else
		return 1 + numeroCifre(num / 10);
}
